package com.ai.dmc.utils.file;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * 
 * <p>Title:</p>
 * <p>Description:</p>
 * <p>Copyright: Copyright (c) 2010</p>
 * <p>Company:亚信科技(中国)有限公司</p>
 * @author  yangtao
 * @version V04ROOC02
 */
public class FileOperation {

	private static final int EOF = -1;
	private static final String LOCK = "_LOCK";  
	private static final int BUFFER_SIZE = 1024 * 1024 / 2;  

	/**
	 * 创建文件,根据给定的路径、文件名、文件内容、编码集创建文件
	 * @param path     	创建文件的具体路径
	 * @param fileName 	文件名称
	 * @param content  	文件内容
	 * @param encode   	编码（建议： UTF-8）
	 * @throws FileNotFoundException
	 * @throws UnsupportedEncodingException
	 */
	public  static void generateFile(String path , String fileName , CharSequence content , String encode) 
	   throws FileNotFoundException, UnsupportedEncodingException{

		// 建目录
		File dirFile = new File(path);
		if (!dirFile.exists()) {
			dirFile.mkdirs();
		}

		// 建文件
		File file = new File(dirFile, fileName);

		// 输出文件
		PrintWriter printWriter = null;
		printWriter = new PrintWriter(file, encode);
		printWriter.println(content);
		printWriter.close();

	}
	
    /** 
     * <des> 文件拷贝, 方法调用结束或抛出异常, 都将关闭输入输出流, 输出流flush </des> 
     * @param in InputStream 
     * @param out OutputStream 
     * @throws IOException 
     * @since 1.0.0 
     */  
    public static void copyFile(InputStream in, OutputStream out) throws IOException{  
            byte[] buffer = new byte[BUFFER_SIZE];  
            int read;  
            while((read = in.read(buffer)) != EOF){  
                out.write(buffer, 0, read);  
            }  
            closeStream(in, out);
    }  
      
    /**
     * <des> 文件拷贝, 方法调用结束或抛出异常, 都将关闭输入输出流, 输出流flush </des> 
     * @param copyFrom 需要被拷贝的文件
     * @param copyTo 拷贝后的文件
     * @throws IOException
     */
    public static void copyFile(String copyFrom, String copyTo) throws IOException{
        copyFile(getFileInputStream(copyFrom), getFileOutputStream(copyTo));  
    }  
  
    /**
     * <des> 文件剪切, 方法调用结束或抛出异常, 都将关闭输入输出流, 输出流flush </des> 
     * @param moveFrom 需要剪切的文件
     * @param moveTo 剪切的目标文件
     * @throws IOException
     */
    public static void moveFile(String moveFrom,String moveTo) throws IOException{
    	File moveFromFile = new File(moveFrom);
    	if(moveFromFile.isFile()){
    		copyFile(moveFrom,moveTo);
    		delete(moveFromFile);
    	}
    }
    /**
     * <des> 字符串内容写出, 方法调用结束或抛出异常, 都将关闭输入输出流, 输出流flush </des>
     * @param text 需要写入的字符串内容
     * @param out 需要写入的输出流
     * @throws IOException
     */
    public static void write(String text, OutputStream out) throws IOException{  
            out.write(text.getBytes());  
            closeStream(out);
    }  
  
    /**
     * <des> 字符串内容写出到文件, 方法调用结束或抛出异常, 都将关闭输入输出流, 输出流flush </des>
     * @param text 需要写入的字符串内容
     * @param file 需要写入的文件
     * @throws IOException
     */
    public static void write(String text, File file) throws IOException{  
        BufferedReader reader = null;  
        BufferedWriter writer = null;  
            reader = new BufferedReader(new StringReader(text));  
            writer = new BufferedWriter(new FileWriter(file));  
            char[] buffer = new char[BUFFER_SIZE];  
            int read;  
            while((read = reader.read(buffer)) != EOF){  
                writer.write(buffer, 0, read);  
            }  
            closeStream(reader, writer);  
    }  
      
    /** 
     * <des> 读取文件内容 </des> 
     * @param pathname 文件全路径名称 
     * @return 读取的文件内容 
     * @throws IOException 
     * @since 1.0.0 
     */  
    public static String readFile(String pathname) throws IOException{  
        return readFile(new File(pathname));  
    }  
      
    /** 
     * <des> 读取文件内容 </des> 
     * @param file 文件对象 
     * @return 读取的文件内容 
     * @throws IOException 
     * @since 1.0.0 
     */  
    public static String readFile(File file) throws IOException{  
        String[] contents = readLineFile(file);  
        StringBuilder builder = new StringBuilder();  
        for(String content : contents){  
            builder.append(content);  
        }  
        return builder.toString();  
    }  
      
    /** 
     * <des> 按行读取文件, 文件的每一行作为数组的一个元素 </des> 
     * @param pathname 文件全路径名称 
     * @return 数组，存放读取文件的每行内容
     * @throws IOException 
     * @since 1.0.0 
     */  
    public static String[] readLineFile(String pathname) throws IOException{  
        return readLineFile(new File(pathname));  
    }  
      
    /** 
     * <des> 按行读取文件, 文件的每一行作为数组的一个元素 </des> 
     * @param file 文件对象 
     * @return 数组 
     * @throws IOException 
     * @since 1.0.0 
     */  
    public static String[] readLineFile(File file) throws IOException{  
        BufferedReader reader = null;  
            reader = new BufferedReader(new FileReader(file));  
            LinkedList<String> list = new LinkedList<String>();  
            String read;  
            while((read = reader.readLine()) != null){  
                list.add(read);  
            }  
            closeStream(reader); 
            return (String[]) list.toArray();
    }  
      
    /** 
     * <des> 获取目录下所有的文件对象 </des> 
     * @param directory 文件目录对象 
     * @return 文件对象列表 
     * @since 1.0.0 
     */  
    public static List<File> listFiles(File directory){  
        return listFiles(directory, null);  
    }  
      
    /** 
     * <des> 获取目录下所有由参数指定类型的文件对象 </des> 
     * @param source 文件目录对象 
     * @param filter 期望得到的文件的后缀名称 
     * @return 文件对象列表 
     * @since 1.0.0 
     */  
    public static List<File> listFiles(File source, String surfix){  
        File[] fileList = source.listFiles();  
        List<File> list = new ArrayList<File>();  
        surfix = surfix == null ? null : surfix.toLowerCase();  
        if(fileList != null && fileList.length > 0){  
            for(File file : fileList){  
                if(file.isFile()){  
                    add(list, file, surfix);  
                }else if(file.isDirectory()){  
                    list.addAll(listFiles(file, surfix));  
                }  
            }  
        }else if(source.isFile()){  
            add(list, source, surfix);  
        }  
        return list;  
    }  
      
    /** 
     * <des> 在参数指定的目录中查找文件 </des> 
     * @param dirpath 文件目录全路径名称 
     * @param filename 查找的文件名称 
     * @return 若查找的到, 则返还该文件对象, 若查找不到, 则返还null 
     * @since 1.0.0 
     */  
    public static File findFile(String dirpath, String filename){  
        return findFile(new File(dirpath), filename);  
    }  
      
    /** 
     * <des> 在参数指定的目录中查找文件 </des> 
     * @param directory 文件目录对象 
     * @param filename 查找的文件名称 
     * @return 若查找的到, 则返还该文件对象, 若查找不到, 则返还null 
     * @since 1.0.0 
     */  
    public static File findFile(File directory, String filename){
    	if(filename.contains(".")) return null;
        String surfix = filename.substring(filename.lastIndexOf(".")+1, filename.length());
        List<File> files = listFiles(directory, surfix);  
        if(files.size() == 0) return null;  
        for(File file : files){  
            if(file.getAbsolutePath().endsWith(filename)){  
                return file;  
            }  
        }  
        return null;  
    }  
      
    /** 
     * <des> 删除文件或目录 </des> 
     * @param file 文件或文件目录对象 
     * @since 1.0.0 
     */  
    public static void delete(File file){  
        synchronized (LOCK) {  
            if(file.isFile()){  
                file.delete();  
            }else if(file.isDirectory()){  
                File[] files = file.listFiles();  
                for(File item : files){  
                    delete(item);  
                }  
            }  
            file.delete();  
        }  
    }  
      
    /** 
     * <des> 创建目录 </des> 
     * @param pathname 目录名称 
     * @return 若目录不存在则创建, 若存在则直接返还true 
     * @since 1.0.0 
     */  
    public static boolean createDir(String pathname){  
        return createDir(new File(pathname));  
    }  
      
    /** 
     * <des> 创建目录 </des> 
     * @param dir 目录对象 
     * @return 若目录不存在则创建, 若存在则直接返还true 
     * @since 1.0.0 
     */  
    public static boolean createDir(File dir){  
        synchronized (LOCK) {  
            if(!dir.exists()){  
                return dir.mkdirs();  
            }  
            return true;  
        }  
    }  
      
      
    /** 
     * <des> 获取FileInputStream实例 </des>
     * @param pathname 文件名
     * @return
     * @throws FileNotFoundException
     */
    public static FileInputStream getFileInputStream(String pathname) throws FileNotFoundException{  
        return getFileInputStream(new File(pathname));  
    }  
      

    /**
     * <p><des> 获取FileInputStream实例 </des></p> 
     * @param file 文件
     * @return
     * @throws FileNotFoundException
     */
    public static FileInputStream getFileInputStream(File file) throws FileNotFoundException{  
            return new FileInputStream(file);  
    }  
      

    /**
     * <p><des> 获取FileOutputStream实例 </des></p>
     * @param pathname 文件名
     * @return
     * @throws FileNotFoundException
     */
    public static FileOutputStream getFileOutputStream(String pathname) throws FileNotFoundException{  
        return getFileOutputStream(new File(pathname), false);  
    }  
      
    /**
     * <p><des> 获取FileOutputStream实例 </des></p> 
     * @param pathname 文件名
     * @param append 是否追加
     * @return
     * @throws FileNotFoundException
     */
    public static FileOutputStream getFileOutputStream(String pathname, boolean append) throws FileNotFoundException{  
        return getFileOutputStream(new File(pathname), append);  
    }  
      
    /** 
     * <p><des> 获取FileOutputStream实例 </des></p> 
     * @param file 文件名
     * @return
     * @throws FileNotFoundException
     */
    public static FileOutputStream getFileOutputStream(File file) throws FileNotFoundException{  
        return getFileOutputStream(file, false);  
    }  
      
    /** 
     * <p><des> 获取FileOutputStream实例 </des></p>
     * @param file 文件
     * @param append 是否追加
     * @return
     * @throws FileNotFoundException
     */
    public static FileOutputStream getFileOutputStream(File file, boolean append) throws FileNotFoundException{   
            return new FileOutputStream(file, append);   
    }  
      
    // 添加文件到列表
    private static void add(List<File> list, File file, String surfix){  
        if(surfix == null){
            list.add(file);  
        }else if(file.getAbsolutePath().toLowerCase().endsWith(surfix)){  
            list.add(file);  
        }  
    }  
    
    /**
     * 
     * @param in
     * @param out
     */
    private static void closeStream(InputStream in,OutputStream out){
    	try {
			in.close();
			out.flush();
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
    	
    }
    
    private static void closeStream(Reader in,Writer out){
    	try {
			in.close();
			out.flush();
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
    	
    }
    
    
    /**
     * 
     * @param out
     */
    private static void closeStream(OutputStream out){
    	try {
			out.flush();
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
    }
    
    private static void closeStream(Reader in){
    	try {
			in.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
    }
	
	public static void main(String[] args) throws Exception {
		String path = "E:\\E" ;
		String fileName = "test.jsp" ;
		generateFile(path, fileName, "我爱世界杯", "UTF-8");
		System.out.println(fileName.substring(fileName.lastIndexOf(".")+1, fileName.length()));
	}
}
